#pragma once
#include <tchar.h>

namespace foo
{
	namespace Util
	{
		// Class Definition
		class Memorizer
		{
		public:
			Memorizer();
			int size;
			int width;
			int length;
			float weight;
			TCHAR* str; // Test how understand expands this macro
		};

		// Function declaration. defined in foo_Util.cpp
		Memorizer* GetNewMemory(size_t, char*);
		// Function delcaration. No definition anywhere.
		Memorizer* MyUnresolvedMethod(size_t, char*, bool);

		// Another declaration that takes more than one line.
		// notice here that the type is on a different line 
		// than the function identifier.
		void
		BigAndWideMethod( char*,
								int,
								float,
								char*);

		// Function definition. inline
		inline Memorizer* GetOldMemory()
		{
			return GetNewMemory(5, "What a character!!");
		}

		// Another inline method
		inline void MakeMemory()
		{
			int i = 5;
			Memorizer* foo = GetOldMemory();
			int j = foo->size;
			int k = i + j;
		}

		// Understand has limited support for templatized classes. Reference to the
		// definition of this class will show the line where 'class Stamper' is. 
		// However the class definition needs to start on the line where it says 'template<typename T>'.
		template<typename T>
		class Stamper
		{
		public:
			Stamper();
		private:
			T* ptr;
			T  mbr;
		};

		/* This class demonstrates classes that are declared and defined inside of
			another class */
		// some comments, seperate from the first one.
		class NestedOuter
		{
		private:
			// This privately declared class has comments too.
			class NestedInner
			{
			private:
				float mData;
			public:
				NestedInner();
				int jack;
				void SetData(float f);
				float GetData();
			};
			NestedInner* mDuck;
			NestedInner* mRabbit;
		public:
			NestedOuter();
			void InLineMethod() // defined and declared inline
			{
				Memorizer* m = new Memorizer();
				m->size = 5;
				int a = m->size;
				m->weight = 7.8f;
				float b = m->weight;
			}
			~NestedOuter();
		};

		struct MySimpleStruct
		{
			int x;
			int y;
			int z;
			double X;
			double Y;
			double Z;
		};
	}
}